<template>
  <el-card class="profile-management-card">
    <template #header>
      <div class="card-header">
        <el-icon><User /></el-icon>
        <span>个人中心 - 人脸与偏好设置</span>
      </div>
    </template>

    <el-row :gutter="40" class="main-layout-row">
      <el-col :span="14">
        <div class="video-area">
          <div 
            class="video-container"
            v-loading="!isSDKReady" 
            element-loading-text="正在加载AI识别引擎..."
          >
            <video ref="videoRef" autoplay muted playsinline></video>
            
            <div class="face-guide-overlay">
              <div class="guide-frame-corners">
                  <div class="corner top-left"></div>
                  <div class="corner top-right"></div>
                  <div class="corner bottom-left"></div>
                  <div class="corner bottom-right"></div>
              </div>
              <div class="guide-text">请将面部置于此框内</div>
            </div>
          </div>

          <div class="action-area">
            <el-button 
              @click="captureAndSave" 
              type="primary" 
              size="large" 
              class="capture-button"
              :disabled="!isSDKReady || isSaving"
            >
              <el-icon v-if="isSaving" class="is-loading"><Loading /></el-icon>
              <el-icon v-else><CameraFilled /></el-icon>
              {{ isSaving ? '正在保存...' : '采集并保存人脸信息' }}
            </el-button>
          </div>
          
          <transition name="feedback-fade">
            <div v-if="feedbackMessage" class="feedback-box" :class="feedbackType">
                <el-icon><component :is="feedbackIcon" /></el-icon>
                <span>{{ feedbackMessage }}</span>
            </div>
          </transition>
        </div>
      </el-col>

      <el-col :span="10">
        <div class="info-area">
          <div class="profile-panel">
              <el-avatar :size="60" :src="authStore.user?.avatar" />
              <div class="user-details">
                  <h4 class="username">{{ user.username }}</h4>
                  <p class="user-status">
                      人脸数据状态：
                      <el-tag :type="hasFaceData ? 'success' : 'danger'" effect="light" size="small" round>
                          {{ hasFaceData ? '已录入' : '未录入' }}
                      </el-tag>
                  </p>
              </div>
          </div>

          <div class="settings-panel">
            <h5 class="panel-title">朗读语音设置</h5>
            <el-form label-position="top">
              <el-form-item label="选择语音包">
                 <el-select 
                    v-model="selectedVoice" 
                    placeholder="请选择喜欢的语音"
                    style="width: 100%;"
                    :loading="availableVoices.length === 0"
                    loading-text="正在加载语音包..."
                  >
                    <el-option
                      v-for="voice in availableVoices"
                      :key="voice.voiceURI"
                      :label="`${voice.name} (${voice.lang})`"
                      :value="voice.voiceURI"
                    />
                  </el-select>
                   <div v-if="availableVoices.length === 0" class="voice-tip">
                      您的浏览器暂未提供中文语音包，将使用默认语音。
                  </div>
              </el-form-item>
              <el-form-item label="朗读语速">
                <el-slider v-model="rate" :min="0.5" :max="2" :step="0.1" @change="handleRateChange" />
              </el-form-item>
              <el-form-item label="朗读音调">
                <el-slider v-model="pitch" :min="0.5" :max="2" :step="0.1" @change="handlePitchChange" />
              </el-form-item>
            </el-form>
          </div>

          <div class="instructions-panel">
            <h5 class="panel-title">操作指南</h5>
            <ul>
              <li><span class="step-circle">1</span>请确保您的脸部光线充足、清晰。</li>
              <li><span class="step-circle">2</span>请勿佩戴帽子、墨镜等遮挡面部的饰品。</li>
              <li><span class="step-circle">3</span>将面部对准视频画面中的引导框，点击“采集”按钮。</li>
              <li><span class="step-circle">4</span>系统会自动捕捉并保存您的面部特征信息。</li>
              <li><span class="step-circle">5</span>此信息将作为您未来人脸识别打卡的唯一依据。</li>
            </ul>
          </div>
        </div>
      </el-col>
    </el-row>
  </el-card>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
import * as faceapi from 'face-api.js';
import { ElMessage } from 'element-plus';
import profileService from '../../services/profileService';
import speechService from '../../services/speechService';
import { useAuthStore } from '../../stores/authStore';
import { User, CameraFilled, Loading, SuccessFilled, WarningFilled, CircleCloseFilled, InfoFilled } from '@element-plus/icons-vue';

// --- 人脸识别相关状态 ---
const videoRef = ref(null);
const isSDKReady = ref(false);
const isSaving = ref(false);
const authStore = useAuthStore();
const user = ref(authStore.user || {});
const hasFaceData = ref(false);
const feedbackMessage = ref('');
let stream = null;
const ssdMobilenetv1Options = new faceapi.SsdMobilenetv1Options({ minConfidence: 0.5 });

// --- 语音选择相关状态 ---
const availableVoices = speechService.availableVoices;
const selectedVoice = computed({
  get() { return speechService.getSelectedVoiceURI(); },
  set(voiceURI) {
    speechService.setSelectedVoice(voiceURI);
    ElMessage.success('默认语音已更新！');
  }
});

// 【新增】语速和音调的响应式引用，直接绑定到 speechService
const rate = ref(speechService.speechRate.value);
const pitch = ref(speechService.speechPitch.value);

// 【新增】处理滑块变化，并调用 service 中的方法进行持久化
const handleRateChange = (newRate) => {
  speechService.setRate(newRate);
};
const handlePitchChange = (newPitch) => {
  speechService.setPitch(newPitch);
};


onMounted(async () => {
  await loadModels();
  startWebcam();
  fetchUserProfile();
});

onBeforeUnmount(() => {
  stopWebcam();
});

const loadModels = async () => {
  const MODEL_URL = '/models';
  try {
    await Promise.all([
      faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL),
      faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
      faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
    ]);
    isSDKReady.value = true;
  } catch (error) {
    ElMessage.error('AI模型加载失败，请刷新页面重试');
  }
};

const startWebcam = async () => {
  try {
    stream = await navigator.mediaDevices.getUserMedia({ video: {} });
    if (videoRef.value) {
      videoRef.value.srcObject = stream;
    }
  } catch (error) {
    ElMessage.error('无法启动摄像头，请检查设备和浏览器权限');
  }
};

const stopWebcam = () => {
  stream?.getTracks().forEach(track => track.stop());
};

const fetchUserProfile = async () => {
  try {
    const profile = await profileService.getProfile();
    user.value = profile;
    hasFaceData.value = !!profile.faceDescriptor;
  } catch (error) {
    ElMessage.error(error.message);
  }
};

const captureAndSave = async () => {
  if (!videoRef.value) return;
  isSaving.value = true;
  feedbackMessage.value = '正在检测人脸...';

  const detections = await faceapi
    .detectAllFaces(videoRef.value, ssdMobilenetv1Options);

  if (detections.length === 0) {
    feedbackMessage.value = '未检测到人脸，请正对摄像头！';
  } else if (detections.length > 1) {
    feedbackMessage.value = '检测到多张人脸，请确保画面中只有您一人！';
  } else if (detections[0].score < 0.9) { 
    feedbackMessage.value = `人脸不够清晰 (置信度: ${detections[0].score.toFixed(2)})，请调整光线或姿势`;
  } else {
    feedbackMessage.value = '检测通过，正在提取特征...';
    const singleResult = await faceapi
      .detectSingleFace(videoRef.value, ssdMobilenetv1Options)
      .withFaceLandmarks()
      .withFaceDescriptor();
    
    if (singleResult) {
      feedbackMessage.value = '特征提取成功，正在保存...';
      const faceDescriptor = JSON.stringify(Array.from(singleResult.descriptor));

      try {
        const message = await profileService.registerFace(faceDescriptor); 
        ElMessage.success(message);
        hasFaceData.value = true;
        feedbackMessage.value = '保存成功！';
      } catch (error) {
        ElMessage.error(error.message);
        feedbackMessage.value = '保存失败！';
      }
    } else {
        feedbackMessage.value = '特征提取失败，请重试';
    }
  }

  setTimeout(() => (feedbackMessage.value = ''), 4000);
  isSaving.value = false;
};

// --- 用于UI反馈的计算属性 ---
const feedbackType = computed(() => {
    const msg = feedbackMessage.value;
    if (msg.includes('成功')) return 'success';
    if (msg.includes('失败') || msg.includes('多张') || msg.includes('未检测到')) return 'error';
    if (msg.includes('清晰')) return 'warning';
    return 'info';
});

const feedbackIcon = computed(() => {
    switch(feedbackType.value) {
        case 'success': return SuccessFilled;
        case 'error': return CircleCloseFilled;
        case 'warning': return WarningFilled;
        default: return InfoFilled;
    }
});
</script>

<style scoped>
/* ========================================================= */
/* 【Final】Thematic Redesign: Professional & Clean            */
/* ========================================================= */

.profile-management-card {
  padding: 10px 20px;
}

.card-header {
  font-size: 18px;
}
.card-header .el-icon {
  color: var(--el-color-primary);
}

.main-layout-row {
  padding: 20px 0;
}

/* --- 左侧视频区域 --- */
.video-area {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.video-container {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  background-color: #000;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid #e0e0e0;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
}
video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
}

/* --- 【核心修改】带隅角的矩形引导框样式 --- */
.face-guide-overlay {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.guide-frame-corners {
    position: absolute;
    width: 60%;
    height: 80%;
    pointer-events: none;
}
.guide-frame-corners .corner {
    position: absolute;
    width: 24px;
    height: 24px;
    border: 3px solid rgba(255, 255, 255, 0.8);
}
.corner.top-left { top: 0; left: 0; border-right: none; border-bottom: none; }
.corner.top-right { top: 0; right: 0; border-left: none; border-bottom: none; }
.corner.bottom-left { bottom: 0; left: 0; border-right: none; border-top: none; }
.corner.bottom-right { bottom: 0; right: 0; border-left: none; border-top: none; }

.guide-text {
  position: absolute;
  bottom: 15%;
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  background-color: rgba(0,0,0,0.3);
  padding: 4px 12px;
  border-radius: 20px;
}

.action-area {
  text-align: center;
  margin: 30px 0 20px 0;
}

.capture-button {
  width: 60%;
  height: 48px;
  font-size: 16px;
  font-weight: 500;
  border-radius: 24px !important;
  box-shadow: 0 4px 12px rgba(var(--color-primary-rgb), 0.3);
}
.capture-button .el-icon {
  font-size: 18px;
  margin-right: 8px;
}

.feedback-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  border-radius: 8px;
  font-weight: 500;
  transition: all 0.3s ease-in-out;
  color: #fff;
}
.feedback-box.info { background-color: #409eff; }
.feedback-box.success { background-color: #67c23a; }
.feedback-box.warning { background-color: #e6a23c; }
.feedback-box.error { background-color: #f56c6c; }

.feedback-fade-enter-active, .feedback-fade-leave-active {
  transition: opacity 0.3s, transform 0.3s;
}
.feedback-fade-enter-from, .feedback-fade-leave-to {
  opacity: 0;
  transform: translateY(10px);
}


/* --- 右侧信息区域 --- */
.info-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  height: 100%;
}
.profile-panel {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
  background-color: #f9fafb;
  border-radius: 12px;
  border: 1px solid #e5e7eb;
}
.user-details {
  display: flex;
  flex-direction: column;
}
.username {
  font-size: 20px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 8px 0;
}
.user-status {
  font-size: 14px;
  color: #606266;
  margin: 0;
}

/* 语音和操作指南面板共享样式 */
.settings-panel,
.instructions-panel {
  background-color: #f9fafb;
  border-radius: 12px;
  border: 1px solid #e5e7eb;
  padding: 20px 25px;
}

.panel-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 20px 0;
  padding-bottom: 15px;
  border-bottom: 1px solid #e5e7eb;
}
.voice-tip {
    font-size: 12px;
    color: #909399;
    margin-top: 8px;
}

.instructions-panel {
  flex-grow: 1;
}
.instructions-panel ul {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.instructions-panel li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 14px;
  color: #606266;
  line-height: 1.6;
}
.step-circle {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background-color: var(--el-color-primary-light-8);
  color: var(--el-color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
  font-size: 12px;
  margin-top: 1px;
}
</style>